package cn.sykj.car.utils;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 根据自定义注解，对比实体类前后变化
 * Created by yuhao on 2021-06-09 .
 */

public class DiffEntityUtils {

    public static Map<String,List<Object>> getDifferent(Object a1,Object a2) throws IntrospectionException,IllegalArgumentException,IllegalAccessException,InvocationTargetException{
        Map<String,List<Object>> map = new HashMap<>();
        Class clazz = a1.getClass();
        Class clazz2 = a2.getClass();
        if(!clazz.equals(clazz2)){
            return map;
        }

        PropertyDescriptor[] pds = Introspector.getBeanInfo(clazz,Object.class).getPropertyDescriptors();

        // 获取当前类的实例域
        Field[] fields = clazz.getDeclaredFields();
        for(Field f : fields){
            // 获取该实例域上的注解
            DiffEntity annotation = f.getAnnotation(DiffEntity.class);
            if(annotation == null){
                continue;
            }
            // 获取注解中的内容
            String actionName = annotation.action();
            // 使用javaBean PropertyDescriptor类型 获取bean的get方法
            String tableFieldName = f.getName();
            for(int i=0;i<pds.length;i++){
                PropertyDescriptor pd = pds[i];
                if(pd.getName().equals(tableFieldName)){
                    // 获取get方法
                    Method readMethod = pd.getReadMethod();
                    Object o1 = readMethod.invoke(a1);
                    Object o2 = readMethod.invoke(a2);
                    if(o1 == null && o2 == null){
                        continue;
                    }
                    if(o1 == null || o2 == null){
                        List<Object> list = new ArrayList<>();
                        list.add(o1);
                        list.add(o2);
                        map.put(actionName,list);
                        continue;
                    }
                    if(!o1.equals(o2)){
                        List<Object> list = new ArrayList<>();
                        list.add(o1);
                        list.add(o2);
                        map.put(actionName,list);
                        continue;
                    }
                }
            }
        }
        return map;
    }
}
